package com.ala4.oxcafe.service.impl;

import com.ala4.oxcafe.boot.page.PageDomain;
import com.ala4.oxcafe.common.utils.collection.CollUtil;
import com.ala4.oxcafe.common.utils.object.ObjectUtil;
import com.ala4.oxcafe.common.utils.text.StrUtil;
import com.ala4.oxcafe.dto.RoleMenuRelDTO;
import com.ala4.oxcafe.entity.RoleInfo;
import com.ala4.oxcafe.entity.RoleMenuRel;
import com.ala4.oxcafe.entity.UserRoleRel;
import com.ala4.oxcafe.exception.BusinessException;
import com.ala4.oxcafe.repository.RoleInfoRepository;
import com.ala4.oxcafe.repository.RoleMenuRelRepository;
import com.ala4.oxcafe.repository.UserRoleRelRepository;
import com.ala4.oxcafe.service.RoleInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 角色信息服务类
 *
 * @author PING
 * @version 1.0.0
 * @date 2025/8/12 12:46
 */
@Service
@AllArgsConstructor
public class RoleInfoServiceImpl implements RoleInfoService {

    private final RoleInfoRepository roleInfoRepository;

    private final RoleMenuRelRepository roleMenuRelRepository;

    private final UserRoleRelRepository userRoleRelRepository;

    @Override
    public IPage<RoleInfo> userInfoPage(PageDomain pageDomain, RoleInfo roleInfo) {
        return roleInfoRepository.selectRoleInfoPage(pageDomain, roleInfo);
    }

    @Override
    public RoleInfo createRoleInfo(RoleInfo roleInfo) {

        List<RoleInfo> roleInfos = roleInfoRepository.selectRoleCode(roleInfo.getRoleCode());

        if (CollUtil.isNotEmpty(roleInfos)) {
            throw new BusinessException("角色编码已存在[{}]", roleInfo.getRoleCode());
        }

        roleInfoRepository.save(roleInfo);

        return roleInfo;
    }

    @Override
    public RoleInfo updateRoleInfo(RoleInfo roleInfo) {
        RoleInfo dbRoleInfo = roleInfoRepository.getById(roleInfo.getId());
        if (ObjectUtil.isNull(dbRoleInfo)) {
            throw new BusinessException("找不到角色信息[{}]", roleInfo.getRoleName());
        }

        dbRoleInfo.setStatus(roleInfo.getStatus());
        dbRoleInfo.setRoleName(roleInfo.getRoleName());
        dbRoleInfo.setRoleSort(roleInfo.getRoleSort());
        dbRoleInfo.setRoleDesc(roleInfo.getRoleDesc());

        roleInfoRepository.updateById(dbRoleInfo);
        return dbRoleInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void allocation(RoleMenuRelDTO roleMenuRelDTO) {
        RoleInfo roleInfo = roleInfoRepository.getById(roleMenuRelDTO.getRoleId());
        if (ObjectUtil.isNull(roleInfo)) {
            throw new BusinessException("找不到角色信息");
        }

        // 删除所有关联关系
        roleMenuRelRepository.remove(Wrappers.<RoleMenuRel>lambdaQuery().eq(RoleMenuRel::getRoleId, roleMenuRelDTO.getRoleId()));

        // 新增关联关系
        List<RoleMenuRel> roleMenuRelList = roleMenuRelDTO.getMenuIds()
                .stream().map(item -> new RoleMenuRel(roleMenuRelDTO.getRoleId(), item)).toList();

        if (CollUtil.isNotEmpty(roleMenuRelList)) {
            roleMenuRelRepository.saveBatch(roleMenuRelList);
        }

        // 新增菜单关联关系
        List<RoleMenuRel> roleMenuPathList = roleMenuRelDTO.getMenuPaths()
                .stream().map(item -> new RoleMenuRel(roleMenuRelDTO.getRoleId(), item)).toList();
        if (CollUtil.isNotEmpty(roleMenuPathList)) {
            roleMenuRelRepository.saveBatch(roleMenuPathList);
        }
    }

    @Override
    public List<RoleInfo> userInfoList(RoleInfo roleInfo) {
        LambdaQueryWrapper<RoleInfo> queryWrapper = Wrappers.<RoleInfo>lambdaQuery();
        queryWrapper.eq(StrUtil.isNotEmpty(roleInfo.getRoleCode()), RoleInfo::getRoleCode, roleInfo.getRoleCode());
        return roleInfoRepository.list(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long roleId) {
        // 删除角色
        RoleInfo roleInfo = roleInfoRepository.getById(roleId);
        if (ObjectUtil.isNull(roleInfo)) {
            throw new BusinessException("角色信息不存在");
        }
        if (roleInfo.getBuiltIn() == 1) {
            throw new BusinessException("系统内置角色不允许删除");
        }
        roleInfoRepository.removeById(roleId);
        // 删除用户关联的角色
        userRoleRelRepository.remove(Wrappers.<UserRoleRel>lambdaQuery().eq(UserRoleRel::getRoleId, roleId));

        // 删除角色关联的菜单
        roleMenuRelRepository.remove(Wrappers.<RoleMenuRel>lambdaQuery().eq(RoleMenuRel::getRoleId, roleId));
    }

    @Override
    public RoleInfo roleInfo(Long roleId) {
        RoleInfo roleInfo = roleInfoRepository.getById(roleId);
        // 查角色的菜单权限
        if (ObjectUtil.isNull(roleInfo)) {
            throw new BusinessException("角色信息不存在");
        }
        List<RoleMenuRel> roleMenuList = roleMenuRelRepository.list(Wrappers.<RoleMenuRel>lambdaQuery().select(RoleMenuRel::getMenuPath).eq(RoleMenuRel::getRoleId, roleId));
        if (CollUtil.isNotEmpty(roleMenuList)) {
            roleInfo.setMenuPaths(roleMenuList.stream().map(RoleMenuRel::getMenuPath).toList());
        }
        return roleInfo;
    }
}
